package ac.github.os.util

import ac.github.os.internal.core.objective.EntityObjective
import ac.github.os.internal.core.objective.Objective
import org.bukkit.entity.LivingEntity
import org.bukkit.entity.Player
import taboolib.library.configuration.ConfigurationSection
import taboolib.module.configuration.SecuredFile
import taboolib.module.database.HostSQL
import taboolib.platform.BukkitPlugin
import java.io.File
import java.lang.StringBuilder
import java.lang.reflect.ParameterizedType
import java.lang.reflect.Type


val serializeGroups = mutableMapOf<Char, String>().apply {
    this[' '] = "&absp"
    this['='] = "&absd"
    this[';'] = "&absf"
    this[';'] = "&absf"
}

fun newfolder(root: File, name: String, files: List<String>): File {
    val file = File(root, name)
    if (!file.exists()) {
        file.mkdirs()
        files.forEach { saveDefaultFile(file, it) }
    }
    return file
}

fun File.listFile(suffix: String = ""): List<File> {
    val listOf = arrayListOf<File>()
    this.listFiles().forEach {
        if (it.isDirectory) {
            listOf.addAll(it.listFile(suffix))
        } else {
            if (suffix == "" || it.name.endsWith(".$suffix")) {
                listOf.add(it)
            }
        }
    }
    return listOf
}
fun saveDefaultFile(file: File, name: String) {
    BukkitPlugin.getInstance().saveResource("${file.name}/$name", false)
}


fun String.serialize(): String {
    val builder = StringBuilder()
    var flag = false
    this.forEach {
        when (it) {
            '\'' -> {
                flag = !flag
            }
            else -> {
                if (serializeGroups.containsKey(it) && flag) {
                    builder.append(serializeGroups[it])
                } else {
                    builder.append(it)
                }

            }
        }
    }
    return builder.toString()
}

fun String.deSerialize(): String {
    var result = this
    serializeGroups.forEach { entry ->
        result = result.replace(entry.value, entry.key + "")
    }
    return result
}


fun String.rebuild(): List<String> {
    if (this.contains("/n")) {
        return this.split("/n")
    }
    return listOf(this)
}

fun List<String>.rebuild(): List<String> {
    val listOf = arrayListOf<String>()
    this.forEach {
        listOf.addAll(it.rebuild())
    }
    return listOf
}

fun getInterfaceT(o: Any, index: Int): Class<*>? {
    return getInterfaceT(o::class.java,index)
}

fun getSuperT(clazz : Class<*>, index: Int): Class<*>? {
    val parameterizedType = clazz.genericSuperclass as ParameterizedType
    val type = parameterizedType.actualTypeArguments[index]
    return checkType(type, index)
}
fun getInterfaceT(clazz : Class<*>, index: Int): Class<*>? {
    val types = clazz.genericInterfaces
    val parameterizedType = types[index] as ParameterizedType
    val type = parameterizedType.actualTypeArguments[index]
    return checkType(type, index)
}




fun LivingEntity.adaptObjective(): Objective {


    return EntityObjective(this)
}

private fun checkType(type: Type?, index: Int): Class<*>? {
    if (type is Class<*>) {
        return type
    } else if (type is ParameterizedType) {
        val t = type.actualTypeArguments[index]
        return checkType(t, index)
    } else {
        val className = if (type == null) "null" else type.javaClass.name
        throw IllegalArgumentException(
            "Expected a Class, ParameterizedType"
                    + ", but <" + type + "> is of type " + className
        )
    }
}

fun ConfigurationSection.getHost(name: String): HostSQL {
    return HostSQL(getConfigurationSection(name) ?: SecuredFile())
}
